trait Base extends { g |
	trait Any extends { this0 | };
    type Boolean = $fs$.Boolean;
    type String = $fs$.String;
	type Unit = $fs$.Unit;
	type Bottom = $fs$.Bottom;
	trait Console extends {
		def println(s :g.String): g.Unit = $fs$.println(s)
		def print(s :g.String): g.Unit = $fs$.print(s)
	};	
	val console :g.Console = new g.Console;
	def error(s :g.String): g.Bottom =  $fs$.error(s)
} ;

trait Peano extends Base { g | 
	trait Nat extends g.Any  { this0 |  // extends g.Any, g.Foo
	// TODO: evaluator can't deal with forward references yet
		def isZero: g.Boolean 
		def pred: g.Nat 
		def printUnary: g.Unit
	
		trait Succ extends g.Nat { this1 | 
			def isZero: g.Boolean = false 
			def pred : g.Nat = this0 
            def printUnary :g.Unit = { 
               val x = this1.pred().printUnary(); 
               g.console.print("1")
            }
		} 
	
		def succ(): g.Nat = new this0.Succ {};
		def add(other : g.Nat): g.Nat = { 
	 		if (this0.isZero()) other else this0.pred().add(other.succ()) 
		} 
	
		def subtract(other : g.Nat): g.Nat = { 
			if (other.isZero()) this0 else this0.succ().subtract(other.pred())
		} 
	} ;
	
	//trait Foo extends {};
} ;

val g = new Peano ; // val g: g.type = new Peano;
trait Zero extends g.Nat { this0 | 
	def isZero(): g.Boolean = true 
	def pred : g.Nat = $fs$.error("error: zero.pred") 
	def printUnary :g.Unit = unit
};

val zero = new Zero;
val two :g.Nat = zero.succ().succ();

val x = g.console.print("two+two in unary: ");
val four = two.add(two);  
val x = four.printUnary();
g.console.println(" done")  // scanner doesn't do empty string ("")

// TODO: scanner freaks out if file does not end in whitespace